package com.jmcgg.freesky.common.util;

import java.util.Calendar;
import java.util.Date;

import org.apache.log4j.Logger;

/**
 * Title: FreeSky Common Java Library <br>
 * Description: FreeSky Common Java Library <br>
 * Copyright: Copyright (c) 2005~2009 www.afss.cn <br>
 * Company: Amei's FreeSky Studio <br>
 * 
 * @author <b>Jacky Chou</b> (AFSS [Amei's FreeSky Studio])
 * @version 1.3.0, 2009-02-10, Update the ID Utility, upgrade the ID to
 *          characters<br>
 *          1.2.1, 2008-08-05, Clean and optimize the source code.<br>
 *          1.2.0, 2008-02-23, Upgrade freesky.jar to 1.2.0 with Struts 2<br>
 *          1.0.0, 2006-05-30, Initial Version
 */
public class IDUtil extends FreeskyUtil {
	/**
	 * Logger for this class
	 */
	private static final Logger logger = Logger.getLogger(IDUtil.class);

	public IDUtil() {
	}

	private static Calendar calendar = Calendar.getInstance();

	public static void getCalendar() {
		calendar.setTime(new Date());
	}

	/**
	 * no tag, FS is set by default. It's a common ID.
	 * 
	 * @return
	 */
	public synchronized static String genID() {
		return genID(Const.FST);
	}

	public synchronized static String genID(String tag) {
		return genFSID(tag, Const.NST60); // return default NST60 ID
	}

	public synchronized static String genFSID(String tag, String nst) {
		String _tag = (tag == null || tag.replace(" ", "").length() < 2) ? Const.FST
				: tag.replace(" ", "").toUpperCase().substring(0, 2);
		return _tag + genNSTMID(nst);
	}

	/**
	 * 
	 * @param nst
	 *            : b=2; o=8; A=10; Z=36; x=60;
	 * @return
	 */
	public synchronized static String genNSTMID(String nst) {
		String tag = nst == null ? Const.NST60 : nst.trim();
		String ret = "";
		if (tag.equals(Const.NST02)) {
			// NS02
		} else if (tag.equals(Const.NST08)) {
			// NS08
		} else if (tag.equals(Const.NST10)) {
			// NS10
		} else if (tag.equals(Const.NST36)) {
			// NS36
			ret = Const.NST36 + NumberSystem36Bean.getInstance().getNSCharsTM();
		} else if (tag.equals(Const.NST60)) {
			// NS60
			ret = Const.NST60 + NumberSystem60Bean.getInstance().getNSCharsTM();
		} else {
			// NS60
			ret = Const.NST60 + NumberSystem60Bean.getInstance().getNSCharsTM();
		}
		return ret;
	}

	public synchronized static String genNSID() {
		return genNSID(Const.NST60);
	}

	/**
	 * NSID: {nst}{YYY}{M}{D}{H}{MI}{SE}{MS}
	 * 
	 * @param nst
	 * @return
	 */
	public synchronized static String genNSID(String nst) {
		NumberSystemBean nsb = null;
		StringBuffer sb = new StringBuffer();
		if (nst.equals(Const.NST60)) {
			// e.g: xYYYMDHmsMS = 11bit
			nsb = NumberSystem60Bean.getInstance();
			getCalendar();
			sb.append(nst);
			sb.append(StringUtil.fillPreZero(3,
					nsb.getNSChars(calendar.get(Calendar.YEAR)))); // YYY
			sb.append(nsb.getNSChars(calendar.get(Calendar.MONTH) + 1)); // M
			sb.append(nsb.getNSChars(calendar.get(Calendar.DAY_OF_MONTH))); // D
			sb.append(nsb.getNSChars(calendar.get(Calendar.HOUR_OF_DAY))); // H
			sb.append(nsb.getNSChars(calendar.get(Calendar.MINUTE))); // m
			sb.append(nsb.getNSChars(calendar.get(Calendar.SECOND))); // s
			sb.append(StringUtil.fillPreZero(2,
					nsb.getNSChars(calendar.get(Calendar.MILLISECOND)))); // MS
		} else if (nst.equals(Const.NST36)) {
			// e.g.: ZYYYMDHmmssMS = 13bit
			nsb = NumberSystem36Bean.getInstance();
			getCalendar();
			sb.append(nst);
			sb.append(StringUtil.fillPreZero(3,
					nsb.getNSChars(calendar.get(Calendar.YEAR)))); // YYY
			sb.append(nsb.getNSChars(calendar.get(Calendar.MONTH) + 1)); // M
			sb.append(nsb.getNSChars(calendar.get(Calendar.DAY_OF_MONTH))); // D
			sb.append(nsb.getNSChars(calendar.get(Calendar.HOUR_OF_DAY))); // H
			sb.append(StringUtil.fillPreZero(2,
					nsb.getNSChars(calendar.get(Calendar.MINUTE)))); // m
			sb.append(StringUtil.fillPreZero(2,
					nsb.getNSChars(calendar.get(Calendar.SECOND)))); // S
			sb.append(StringUtil.fillPreZero(2,
					nsb.getNSChars(calendar.get(Calendar.MILLISECOND)))); // MS
		}

		if (logger.isInfoEnabled()) {
			logger.info(calendar.getTime());
			logger.info("genNSID(String) - StringBuffer sb=" + sb);
		}

		return sb.toString();
	}

	/**
	 * return FreeSky Date Format: YYYY-MM-DD HH:mm:ss<br>
	 * Please note that the SSS is ignored from nsId, so the returned time
	 * cannot match to original ID.
	 * 
	 * @param nsId
	 * @return
	 */
	public static String parseNSID(String nsId) {
		if (nsId == null || nsId.trim().length() < 11)
			return "";
		NumberSystemBean nsb = null;
		StringBuffer sb = new StringBuffer();
		if (nsId.substring(0, 1).equals(Const.NST60)) {
			// xYYYMDHmsMS
			nsb = NumberSystem60Bean.getInstance();
			sb.append(StringUtil.fillPreZero(4,
					nsb.getDecimal(nsId.substring(1, 4)))); // YYY
			sb.append("-");
			sb.append(StringUtil.fillPreZero(2,
					nsb.getDecimal(nsId.substring(4, 5)))); // M
			sb.append("-");
			sb.append(StringUtil.fillPreZero(2,
					nsb.getDecimal(nsId.substring(5, 6)))); // D
			sb.append(" ");
			sb.append(StringUtil.fillPreZero(2,
					nsb.getDecimal(nsId.substring(6, 7))));// H
			sb.append(":");
			sb.append(StringUtil.fillPreZero(2,
					nsb.getDecimal(nsId.substring(7, 8)))); // m
			sb.append(":");
			sb.append(StringUtil.fillPreZero(2,
					nsb.getDecimal(nsId.substring(8, 9)))); // s
		} else if (nsId.substring(0, 1).equals(Const.NST36)) {
			// ZYYYMDHmmssMS
			nsb = NumberSystem36Bean.getInstance();
			sb.append(StringUtil.fillPreZero(4,
					nsb.getDecimal(nsId.substring(1, 4)))); // YYY
			sb.append("-");
			sb.append(StringUtil.fillPreZero(2,
					nsb.getDecimal(nsId.substring(4, 5)))); // M
			sb.append("-");
			sb.append(StringUtil.fillPreZero(2,
					nsb.getDecimal(nsId.substring(5, 6)))); // D
			sb.append(" ");
			sb.append(StringUtil.fillPreZero(2,
					nsb.getDecimal(nsId.substring(6, 7))));// H
			sb.append(":");
			sb.append(StringUtil.fillPreZero(2,
					nsb.getDecimal(nsId.substring(7, 9)))); // mm
			sb.append(":");
			sb.append(StringUtil.fillPreZero(2,
					nsb.getDecimal(nsId.substring(9, 11)))); // ss
		}

		return sb.toString();
	}

	public static String parsePureDateNSID(String nsId) {
		return parseNSID(nsId).replace("-", "").replace(":", "")
				.replace(" ", "");
	}
}
